﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Media.Media3D;


namespace PlanetsAndOrbs
{
    class TransparentSphere : Sphere
    {
        Vector3D surfaceFilter_, volumetricFilter_;
        double density_;

        public TransparentSphere(Vector3D center, double radius, double density, Color surfaceFilter, Color volumetricEmission)
            : base(center, radius)
        {
            density_ = density;
            surfaceFilter_ = PixelRenderer.color2V3D(surfaceFilter);
            volumetricFilter_ = PixelRenderer.color2V3D(volumetricEmission);
            normalizeColors(ref surfaceFilter_, ref volumetricFilter_);
        }

        public override bool trace(ref Vector3D origin, ref Vector3D ray, out Vector3D filter, out Vector3D emission)
        {
            // calculate the normal vector
            Vector3D radius = origin - center_;
            Vector3D normal = new Vector3D(radius.X, radius.Y, radius.Z);   // copy 
            normal.Normalize();
            
            double alpha = Math.Abs(Vector3D.DotProduct(ray, normal));
            
            Vector3D innerRay = ray - normal * density_;    // if density == 0 will not change direction
            Vector3D innerRayNormalized = new Vector3D(innerRay.X, innerRay.Y, innerRay.Z);
            innerRayNormalized.Normalize();

            double innerDistance = Math.Abs(Vector3D.DotProduct(radius, innerRayNormalized)) * 2;
            filter = surfaceFilter_ * (1 - alpha) + volumetricFilter_ * innerDistance / (1 + innerDistance);
            emission = new Vector3D();             // this obj does not emit anything 

            origin += innerDistance * innerRayNormalized;    // the other side
            
            normal = origin - center_;
            normal.Normalize();
            ray = innerRay - normal * density_;    // if density == 0 will not change direction
            ray.Normalize();
            return false;
        }
    }
}
